using System;
using Dapr.Client;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using EasyDapr.Domain;
using EasyDapr.Infrastructure;
using EasyDapr.Infrastructure.Attribute;
using EasyDapr.Infrastructure.Dapr;

namespace InventoryService.Infrastructure.PubSub
{
    /// <summary>
    /// 
    /// </summary>
    [DaprComponent]
    public class DaprInventoryCreatedPublisher : IDaprPublisher
    {
        private readonly ILogger<DaprInventoryCreatedPublisher> _logger;
        private readonly DaprClient _daprClient;

        private const string Channel = "InventoryCreated";

        public DaprInventoryCreatedPublisher(DaprClient daprClient, ILogger<DaprInventoryCreatedPublisher> logger)
        {
            _daprClient = daprClient;
            _logger = logger;
        }

        public async Task Publish(IDomainEvent @event, CancellationToken cancellationToken)
        {
            var jsonContent = JsonSerializer.Serialize(@event, @event.GetType(), new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });

            _logger.LogInformation($"[{nameof(DaprInventoryCreatedPublisher)}] - Prepare to publish: {jsonContent}");

            await _daprClient.PublishEventAsync(
                Consts.PubSubName, Channel,
                Convert.ChangeType(@event, @event.GetType()),
                cancellationToken);
            
            _logger.LogInformation($"[{nameof(DaprInventoryCreatedPublisher)}] - Published: {jsonContent}");
        }
    }
}